package rsj.job.statistic;

import com.alibaba.fastjson.JSON;
import com.rlyy.aibase.utils.base.TableNode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import rsj.api.org.importdata.ImportEasyExcelInvoke;
import rsj.db.dbutils.UniqueID;
import rsj.sql.statistic.StatisticTestUsageDao;

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 定时统计测试环境产品使用情况
 *
 * @author yuanqinglong
 * @since 2021/3/9 18:09
 */
@Component
public class StatisticTestUsage implements IStatisticUsageJob {


    @Autowired
    private StatisticTestUsageDao statisticsTestUsageDao;


    /**
     * 执行统计数据
     *
     * @param statisticsDate 统计日期
     * @param orgId          org id
     * @param environment    环境
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void performStatistics(LocalDate statisticsDate, String orgId, String environment) {
        TableNode tableNode = statisticsTestUsageDao.statisticTestUsage(statisticsDate, orgId, ImportEasyExcelInvoke.IS_COST);
        if (tableNode.length() > 0) {
            List<StatisticColumnEntity> statisticColumnEntities = JSON.parseArray(tableNode.toJson(), StatisticColumnEntity.class);
            statisticsTestUsageDao.addToStatisticalTableSql(statisticColumnEntities, statisticsDate, environment);
        }
    }

    /**
     * 统计产品使用量SQL语句
     *
     * @param statisticsDate 统计日期
     * @param orgId          统计机构id（如果传递机构id 则是手动触发此机构的统计 、未传递机构id统计指定统计日期的所有机构的使用情况）
     * @return SQL
     */
    @Override
    public String statisticalSqlStatement(LocalDate statisticsDate, String orgId, String cost) {
        String orgCondition = StringUtils.isBlank(orgId) ? "" : " AND org_id = #{orgId}";
        String dateZone = "(log_storagetime < '" + statisticsDate + "' AND log_storagetime >= '" + statisticsDate.minusDays(1) + "')";
        return " SELECT log_prod_uid ,prod_name ,COUNT(*) AS stat_useamount, " +
                " log_orgp_id,org_id,org_sname,log_storagetime::DATE as log_storagetime " +
                " FROM sys.oper_test_log LEFT JOIN sys.sys_prod ON prod_uid = log_prod_uid " +
                " LEFT JOIN sys.sys_orgp orgp ON orgp.orgp_id =log_orgp_id LEFT JOIN sys.sys_org ON org_id = orgp.orgp_org_id " +
                " WHERE  log_iscost = #{cost} AND " + dateZone + orgCondition +
                " GROUP BY log_orgp_id,log_prod_uid,prod_name,org_id,org_sname,log_storagetime::DATE; ";
    }


    /**
     * 添加到sql统计表
     *
     * @param statisticColumnEntities 数据列的实体
     * @param statisticsDate          统计日期
     * @param environment             环境
     * @return {@link String}
     */
    @Override
    public String addToStatisticalTableSql(List<StatisticColumnEntity> statisticColumnEntities, LocalDate statisticsDate, String environment) {
        String insert = " INSERT INTO sys.sys_stat (stat_id, stat_org_id, stat_org_sname, stat_orgp_id, stat_prod_uid, stat_prod_name, stat_env, stat_date,stat_useamount) VALUES ";
        String upset = " ON CONFLICT(stat_date,stat_orgp_id,stat_org_id,stat_env)" +
                " DO UPDATE SET stat_useamount = EXCLUDED.stat_useamount," +
                " stat_prod_name = EXCLUDED.stat_prod_name," +
                " stat_prod_uid = EXCLUDED.stat_prod_uid";
        String values = statisticColumnEntities.stream().map(statisticColumnEntity -> "(" +
                "'" + UniqueID.generateId() + "', " +
                "'" + statisticColumnEntity.getOrgId() + "', " +
                "'" + statisticColumnEntity.getOrgSname() + "', " +
                "'" + statisticColumnEntity.getLogOrgpId() + "', " +
                "'" + statisticColumnEntity.getLogProdUid() + "', " +
                "'" + statisticColumnEntity.getProdName() + "', " +
                "#{environment}, " +
                "'#{statisticsDate}', " +
                "'" + statisticColumnEntity.getStatUseamount() + "'" +
                ")").collect(Collectors.joining(","));
        return insert + values + upset;
    }
}
